﻿using System;
using System.Collections.Generic;
using System.Web;
using System.Text;
using System.Security.Cryptography;
using System.IO;
using WLMCoreLibrary;
using System.Data;
using System.Data.Odbc;


namespace MWS_AddDirectory
{
    public enum PaymentProviders
    {
        oxxo,paypal,seveneleven
    }

    public class Payment
    {

        public Payment()
        {
        }
public AnuncioTransaccion GetPaymentTicketDineroMail(AnuncioTransaccion transaccion,Anuncio anuncio,Cliente cliente)
        {
            //Consulta del balance en la cuenta del usuario.
            string MerchantId=transaccion.id.ToString();
            string UniqueID=transaccion.id.ToString();
            string Currency=transaccion.currency;
            string Amount = transaccion.monto.ToString();
            string Provider=transaccion.PaymentProvider.ToString();
            string Hash = "";
            string Subject = "Subject Test";
            string Message = "Message Test";
            //MerchantId = "12";//Valor MerchantTransactionId
            //UniqueID = "12";//Valor UniqueId
            //Currency = "MXN";
            //Amount = "365.00";
            //Provider = "oxxo";
            bool Crypt = true; //Valor de encriptación en false (sin encriptación)
            DineroMailAPI.Item oItem = new DineroMailAPI.Item();

            oItem.Amount =transaccion.monto.ToString();
            oItem.Code = "A"+anuncio.id;
            oItem.Currency = transaccion.currency;
            oItem.Description = transaccion.Concepto;
            oItem.Name = transaccion.Concepto;
            oItem.Quantity = "1";

            DineroMailAPI.Item[] oItems = { oItem };

            DineroMailAPI.Buyer oBuyer = new DineroMailAPI.Buyer();
            oBuyer.Address = cliente.Direccion;
            oBuyer.City = cliente.Direccion;
            oBuyer.Country = "Mexico";
            oBuyer.Email = "info@"+DeCurrentDomain.DomainName;
            oBuyer.LastName = cliente.Apellidos;
            oBuyer.Name = cliente.Nombre;
            oBuyer.Phone = cliente.Telefono;
            //Creamos una instancia del objeto APICredential
            DineroMailAPI.APICredential Credential = new DineroMailAPI.APICredential();

            //VALORES PARA PRODUCCION
            Credential.APIPassword = "OL34YP254THYG632ZXCHH58H";
            Credential.APIUserName = "DMAPI060710319";
            //Valores para SANDBOX
            //Credential.APIPassword = "TEST-TEST-TEST-TEST-TEST";
            //Credential.APIUserName = "TEST";

            string sConcatItem = oItem.Amount + oItem.Code + oItem.Currency + oItem.Description + oItem.Name + oItem.Quantity;

            string sConcatBuyer = oBuyer.Name + oBuyer.LastName + oBuyer.Email + oBuyer.Address + oBuyer.Phone + oBuyer.Country + oBuyer.City;

            Hash = MerchantId + UniqueID + sConcatItem + sConcatBuyer + Provider + Subject + Message + Credential.APIPassword.ToString();

            DMCrypt CryptObject = new DMCrypt();
            //si se desea enviar encriptado
            if (Crypt)
            {
                CryptObject.Key = Encoding.ASCII.GetBytes(Credential.APIPassword);
                MerchantId = CryptObject.Encrypt(MerchantId);
                UniqueID = CryptObject.Encrypt(UniqueID);
                Provider = CryptObject.Encrypt(Provider);
                Subject = CryptObject.Encrypt(Subject);
                Message = CryptObject.Encrypt(Message);

                foreach (DineroMailAPI.Item Item in oItems)
                {
                    oItem.Amount = CryptObject.Encrypt(oItem.Amount);
                    oItem.Code = CryptObject.Encrypt(oItem.Code);
                    oItem.Currency = CryptObject.Encrypt(oItem.Currency);
                    oItem.Description = CryptObject.Encrypt(oItem.Description);
                    oItem.Name = CryptObject.Encrypt(oItem.Name);
                    oItem.Quantity = CryptObject.Encrypt(oItem.Quantity);

                }
                oBuyer.Name = CryptObject.Encrypt(oBuyer.Name);
                oBuyer.LastName = CryptObject.Encrypt(oBuyer.LastName);
                oBuyer.Email = CryptObject.Encrypt(oBuyer.Email);
                oBuyer.Address = CryptObject.Encrypt(oBuyer.Address);
                oBuyer.Phone = CryptObject.Encrypt(oBuyer.Phone);
                oBuyer.Country = CryptObject.Encrypt(oBuyer.Country);
                oBuyer.City = CryptObject.Encrypt(oBuyer.City);
            }

            Hash = CryptObject.GetHashMD5(Hash);
            DineroMailAPI.DMAPI Client = new DineroMailAPI.DMAPI();

            //consultamos el servicio web
            DineroMailAPI.ResultDoPaymentWithReference PaymentWithReferenceResult = Client.DoPaymentWithReference(Credential, Crypt, MerchantId, oItems, oBuyer, Provider, Subject, Message, UniqueID, Hash);

            //mostramos la respuesta de la operación en pantalla.
            string sResult = "Status: " + PaymentWithReferenceResult.Status.ToString() + "<br>";
            sResult = sResult + "Message: " + PaymentWithReferenceResult.Message.ToString() + "<br>";
            sResult = sResult + "MerchantTransactionId: " + PaymentWithReferenceResult.MerchantTransactionId.ToString() + "<br>";
            sResult = sResult + "UniqueMessageId: " + PaymentWithReferenceResult.UniqueMessageId.ToString() + "<br>";
            if (PaymentWithReferenceResult.Status.ToString() == "COMPLETED")
            {
                transaccion.transactID = PaymentWithReferenceResult.TransactionId;
                transaccion.codigoBarras = PaymentWithReferenceResult.BarcodeDigits;
                transaccion.fechaVecimiento = DateTime.Now.AddDays(14);
                transaccion.BarcodeImageUrl = PaymentWithReferenceResult.BarcodeImageUrl;
                transaccion.VoucherUrl = PaymentWithReferenceResult.VoucherUrl;
                transaccion.Save();
                sResult = sResult + "MerchantTransactionId: " + PaymentWithReferenceResult.MerchantTransactionId.ToString() + "<br>";
                sResult = sResult + "TransactionId: " + PaymentWithReferenceResult.TransactionId.ToString() + "<br>";
                sResult = sResult + "BarcodeDigits: " + PaymentWithReferenceResult.BarcodeDigits + "<br>";
                sResult = sResult + "UrlImage: " + PaymentWithReferenceResult.BarcodeImageUrl.ToString() + "<br>";
                sResult = sResult + "Voucher: " + PaymentWithReferenceResult.VoucherUrl.ToString();
            }

            return transaccion;
        }
        public AnuncioTransaccion GetPaymentTicket(AnuncioTransaccion transaccion,bool cosa)
        {
            //Consulta del balance en la cuenta del usuario.
            string MerchantId=transaccion.id.ToString();
            string UniqueID=transaccion.id.ToString();
            string Currency=transaccion.currency;
            string Amount = transaccion.monto.ToString();
            string Provider=transaccion.PaymentProvider.ToString();
            string Hash = "";
            //MerchantId = "12";//Valor MerchantTransactionId
            //UniqueID = "12";//Valor UniqueId
            //Currency = "MXN";
            //Amount = "365.00";
            //Provider = "oxxo";
            bool Crypt = true; //Valor de encriptación en false (sin encriptación)

            //Creamos una instancia del objeto APICredential
            DineroMailAPI.APICredential Credential = new DineroMailAPI.APICredential();

            //VALORES PARA PRODUCCION
            Credential.APIPassword = "OL34YP254THYG632ZXCHH58H";
            Credential.APIUserName = "DMAPI060710319";
            //Valores para SANDBOX
            //Credential.APIPassword = "TEST-TEST-TEST-TEST-TEST";
            //Credential.APIUserName = "TEST";

            //preparamos la cadena de texto a utilizar en el hash
            Hash = MerchantId + UniqueID + Currency + Amount + Provider + Credential.APIPassword.ToString();

            DMCrypt CryptObject = new DMCrypt();
            //si se desea enviar encriptado
            if (Crypt)
            {
                CryptObject.Key = Encoding.ASCII.GetBytes(Credential.APIPassword);
                MerchantId = CryptObject.Encrypt(MerchantId);
                UniqueID = CryptObject.Encrypt(UniqueID);
                Currency = CryptObject.Encrypt(Currency);
                Amount = CryptObject.Encrypt(Amount);
                Provider = CryptObject.Encrypt(Provider);
            }
            Hash = CryptObject.GetHashMD5(Hash);
            DineroMailAPI.DMAPI Client = new DineroMailAPI.DMAPI();

            //consultamos el servicio web
            DineroMailAPI.ResultGetPaymentTicket PaymentTicketResult = Client.GetPaymentTicket(Credential, Crypt, Currency, Amount, Provider, MerchantId, UniqueID, Hash);

            //mostramos la respuesta de la operación en pantalla.
            string sResult = "Status: " + PaymentTicketResult.Status.ToString() + "<br>";
            sResult = sResult + "Message: " + PaymentTicketResult.Message.ToString() + "<br>";
            sResult = sResult + "MerchantTransactionId: " + PaymentTicketResult.MerchantTransactionId.ToString() + "<br>";
            sResult = sResult + "UniqueMessageId: " + PaymentTicketResult.UniqueMessageId.ToString() + "<br>";
            if (PaymentTicketResult.Status.ToString() == "COMPLETED")
            {
                transaccion.transactID = PaymentTicketResult.TransactionId;
                transaccion.codigoBarras = PaymentTicketResult.BarcodeDigits;
                transaccion.fechaVecimiento = DateTime.Now.AddDays(4);
                transaccion.Save();
                sResult = sResult + "MerchantTransactionId: " + PaymentTicketResult.MerchantTransactionId.ToString() + "<br>";
                sResult = sResult + "TransactionId: " + PaymentTicketResult.TransactionId.ToString() + "<br>";
                sResult = sResult + "BarcodeDigits: " + PaymentTicketResult.BarcodeDigits + "<br>";
                sResult = sResult + "UrlImage: " + PaymentTicketResult.BarcodeImageUrl.ToString() + "<br>";
                sResult = sResult + "Voucher: " + PaymentTicketResult.VoucherUrl.ToString();
            }

            return transaccion;
        }
    }

    public class DMCrypt
    {
        private TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();
        private UTF8Encoding utf8 = new UTF8Encoding();

        private byte[] keyValue;
        private byte[] iVValue;

        public byte[] Key
        {
            get { return keyValue; }
            set
            {
                keyValue = value;

                this.iVValue = Encoding.ASCII.GetBytes("uL%&(#(f");
            }
        }

        public byte[] iV
        {
            get { return iVValue; }

            set { iVValue = value; }
        }

        public DMCrypt()
        {
        }

        public byte[] Decrypt(byte[] bytes)
        {
            return Transform(bytes, des.CreateDecryptor(this.keyValue, this.iVValue));
        }

        public byte[] Encrypt(byte[] bytes)
        {

            return Transform(bytes, des.CreateEncryptor(this.keyValue, this.iVValue));
        }

        public string Decrypt(string text)
        {
            byte[] input = Convert.FromBase64String(text);
            byte[] output = Transform(input, des.CreateDecryptor(this.keyValue, this.iVValue));
            return utf8.GetString(output);
        }

        public string Encrypt(string text)
        {
            byte[] input = utf8.GetBytes(text);
            byte[] output = Transform(input, des.CreateEncryptor(this.keyValue, this.iVValue));
            return Convert.ToBase64String(output);
        }

        private byte[] Transform(byte[] input, ICryptoTransform cryptoTransform)
        {
            // Create the necessary streams
            MemoryStream memory = new MemoryStream();
            CryptoStream stream = new CryptoStream(memory, cryptoTransform, CryptoStreamMode.Write);

            // Transform the bytes as requesed
            stream.Write(input, 0, input.Length);
            stream.FlushFinalBlock();

            // Read the memory stream and convert it back into byte array
            memory.Position = 0;
            byte[] result = new byte[memory.Length];
            memory.Read(result, 0, result.Length);

            // Clean up
            memory.Close();
            stream.Close();

            // Return result
            return result;
        }

        public string GetHashMD5(string Value)
        {
            MD5CryptoServiceProvider MD5Provider = new MD5CryptoServiceProvider();
            byte[] data = Encoding.ASCII.GetBytes(Value);
            data = MD5Provider.ComputeHash(data);
            string ret = "";
            for (int i = 0; i < data.Length; i++)
            {
                ret += data[i].ToString("x2").ToLower();
            }
            return ret;
        }
    }

    public class AnuncioTransaccion : BaseClass
    {
        #region private fields
        private String _GUID;
        private int _idAnuncio;
        private int _idCliente;
        private int _idPromotor;
        private double _monto;
        private DateTime _fechaVecimiento;
        private DateTime _fechaRealizacion;
        private int _status;
        private String _codigoBarras;
        private String _Concepto;
        private String _currency;
        private String _transactID;
        private String _provider;
        private String _BarcodeImageUrl;
        private String _VoucherUrl;
        private PaymentProviders _paymentProvider;
        private Anuncio _anuncio;


        #endregion

        #region public properties
        public String GUID {get;set; }
        public int idAnuncio {get;set; }
        public int idCliente {get;set; }
        public int idPromotor {get;set; }
        public double monto {get;set; }
        public DateTime fechaVecimiento {get;set; }
        public DateTime fechaRealizacion {get;set; }
        public int status {get;set; }
        public String codigoBarras {get;set; }
        public String Concepto {get;set; }
        public String currency {get;set; }
        public String transactID {get;set; }
        public String Provider
        {
           get;set;
     
        }
        public String BarcodeImageUrl
        {
           get;set;
   
        }
        public String VoucherUrl
        {
           get;set;

        }
        public PaymentProviders PaymentProvider
        {
            get;
            set;
        }
        public Anuncio Anuncio
        {
           get;set;
        }
        #endregion

        #region constructors
        public AnuncioTransaccion()
        {
        }

        public AnuncioTransaccion(ref dbConnector ConexionDB)
        {
            ConexionDBInterna = ConexionDB;
            WLMClassBinder classBinder = new WLMClassBinder(ref ConexionDBInterna);
            id = classBinder.NewRecord("ANUNCIOTRANSACCIONES");
            string queryString = "";
            queryString = "SELECT * FROM ANUNCIOTRANSACCIONES WHERE id='" + id + "'";
            GetRecord(queryString);
        }

        public AnuncioTransaccion(int registryId, ref dbConnector ConexionDB)
        {
            ConexionDBInterna = ConexionDB;
            string queryString = "";
            queryString = "SELECT * FROM ANUNCIOTRANSACCIONES WHERE id='" + registryId + "'";
            WLMClassBinder classBinder = new WLMClassBinder(ref ConexionDBInterna);
            this.GetRecord(queryString);
        }
        public AnuncioTransaccion(DataRow dataRow)
        {

            this.GetRecord(dataRow);
        }
        #endregion

        #region public methods
        public void Delete()
        {
            string queryString = "";
            queryString = "DELETE FROM ANUNCIOTRANSACCIONES WHERE id='" + id + "'";
            ConexionDBInterna.ExecuteCommand(queryString);
        }
        #endregion

        #region Private Methods
        private void GetRecord(string queryString)
        {
            OdbcDataReader reader = ConexionDBInterna.ExecuteReader(queryString);
            if (reader.HasRows)
            {
                if (!reader.IsDBNull(reader.GetOrdinal("id")))
                    id = (System.Int32)reader["id"];
                if (!reader.IsDBNull(reader.GetOrdinal("fechaCreacion")))
                    fechaCreacion = Convert.ToDateTime(reader["fechaCreacion"]);
                if (!reader.IsDBNull(reader.GetOrdinal("fechaModificacion")))
                    fechaModificacion = Convert.ToDateTime(reader["fechaModificacion"]);
                if (!reader.IsDBNull(reader.GetOrdinal("idUsuario")))
                    idUsuario = (System.Int32)reader["idUsuario"];
                if (!reader.IsDBNull(reader.GetOrdinal("idUsuarioModificacion")))
                    idUsuarioModificacion = (System.Int32)reader["idUsuarioModificacion"];
                if (!reader.IsDBNull(reader.GetOrdinal("GUID")))
                    GUID = (System.String)reader["GUID"];
                if (!reader.IsDBNull(reader.GetOrdinal("idAnuncio")))
                    idAnuncio = (System.Int32)reader["idAnuncio"];
                if (!reader.IsDBNull(reader.GetOrdinal("idCliente")))
                    idCliente = (System.Int32)reader["idCliente"];
                if (!reader.IsDBNull(reader.GetOrdinal("idPromotor")))
                    idPromotor = (System.Int32)reader["idPromotor"];
                if (!reader.IsDBNull(reader.GetOrdinal("monto")))
                    if (!reader.IsDBNull(reader.GetOrdinal("fechaVecimiento")))
                        fechaVecimiento = Convert.ToDateTime(reader["fechaVecimiento"]);
                if (!reader.IsDBNull(reader.GetOrdinal("fechaRealizacion")))
                    fechaRealizacion = Convert.ToDateTime(reader["fechaRealizacion"]);
                if (!reader.IsDBNull(reader.GetOrdinal("status")))
                    status = (System.Int32)reader["status"];
                if (!reader.IsDBNull(reader.GetOrdinal("codigoBarras")))
                    codigoBarras = (System.String)reader["codigoBarras"];
                if (!reader.IsDBNull(reader.GetOrdinal("Concepto")))
                    Concepto = (System.String)reader["Concepto"];
                if (!reader.IsDBNull(reader.GetOrdinal("currency")))
                    currency = (System.String)reader["currency"];
                if (!reader.IsDBNull(reader.GetOrdinal("transactID")))
                    transactID = (System.String)reader["transactID"];
                if (!reader.IsDBNull(reader.GetOrdinal("provider")))
                    Provider = (System.String)reader["provider"];
                if (!reader.IsDBNull(reader.GetOrdinal("VoucherUrl")))
                    VoucherUrl = (System.String)reader["VoucherUrl"];
                if (!reader.IsDBNull(reader.GetOrdinal("BarcodeImageUrl")))
                    BarcodeImageUrl = (System.String)reader["BarcodeImageUrl"];
            }
        }


        private void GetRecord(DataRow dataRow)
        {
            if (dataRow != null)
            {
                if (dataRow["id"] != null)
                    id = (System.Int32)dataRow["id"];
                if (dataRow["fechaCreacion"] != null)
                    fechaCreacion = (System.DateTime)dataRow["fechaCreacion"];
                if (dataRow["fechaModificacion"] != null)
                    fechaModificacion = (System.DateTime)dataRow["fechaModificacion"];
                if (dataRow["idUsuario"] != null)
                    idUsuario = (System.Int32)dataRow["idUsuario"];
                if (dataRow["idUsuarioModificacion"] != null)
                    idUsuarioModificacion = (System.Int32)dataRow["idUsuarioModificacion"];
                if (dataRow["GUID"] != null)
                    GUID = (System.String)dataRow["GUID"];
                if (dataRow["idAnuncio"] != null)
                    idAnuncio = (System.Int32)dataRow["idAnuncio"];
                if (dataRow["idCliente"] != null)
                    idCliente = (System.Int32)dataRow["idCliente"];
                if (dataRow["idPromotor"] != null)
                    idPromotor = (System.Int32)dataRow["idPromotor"];
                if (dataRow["monto"] != null)
                    if (dataRow["fechaVecimiento"] != null)
                        fechaVecimiento = (System.DateTime)dataRow["fechaVecimiento"];
                if (dataRow["fechaRealizacion"] != null)
                    fechaRealizacion = (System.DateTime)dataRow["fechaRealizacion"];
                if (dataRow["status"] != null)
                    status = (System.Int32)dataRow["status"];
                if (dataRow["codigoBarras"] != null)
                    codigoBarras = (System.String)dataRow["codigoBarras"];
                if (dataRow["Concepto"] != null)
                    Concepto = (System.String)dataRow["Concepto"];
                if (dataRow["currency"] != null)
                    currency = (System.String)dataRow["currency"];
                if (dataRow["transactID"] != null)
                    transactID = (System.String)dataRow["transactID"];
                if (dataRow["provider"] != null)
                    Provider = (System.String)dataRow["provider"];
                if (dataRow["BarcodeImageUrl"] != null)
                    BarcodeImageUrl = (System.String)dataRow["BarcodeImageUrl"];
                if (dataRow["VoucherUrl"] != null)
                    VoucherUrl = (System.String)dataRow["VoucherUrl"];
            }
        }


        protected override void UpdateBind()
        {
            StringBuilder strCommand = new StringBuilder();
            strCommand.Append("UPDATE ANUNCIOTRANSACCIONES set ");
            strCommand.Append("fechaModificacion='" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "'");
            strCommand.Append(",idUsuarioModificacion='" + idUsuarioModificacion.ToString() + "'");
            strCommand.Append(",GUID=\"" + WLMFunctions.comillas(GUID) + "\"");
            strCommand.Append(",idAnuncio='" + idAnuncio.ToString() + "'");
            strCommand.Append(",idCliente='" + idCliente.ToString() + "'");
            strCommand.Append(",idPromotor='" + idPromotor.ToString() + "'");
            strCommand.Append(",monto=\"" + WLMFunctions.comillas(monto.ToString()) + "\"");
            strCommand.Append(",fechaVecimiento='" + fechaVecimiento.ToString("yyyy-MM-dd HH:mm:ss") + "'");
            strCommand.Append(",fechaRealizacion='" + fechaRealizacion.ToString("yyyy-MM-dd HH:mm:ss") + "'");
            strCommand.Append(",status='" + status.ToString() + "'");
            strCommand.Append(",codigoBarras=\"" + WLMFunctions.comillas(codigoBarras) + "\"");
            strCommand.Append(",Concepto=\"" + WLMFunctions.comillas(Concepto) + "\"");
            strCommand.Append(",currency=\"" + WLMFunctions.comillas(currency) + "\"");
            strCommand.Append(",transactID=\"" + WLMFunctions.comillas(transactID) + "\"");
            strCommand.Append(",provider=\"" + WLMFunctions.comillas(Provider) + "\"");
            strCommand.Append(",VoucherUrl=\"" + WLMFunctions.comillas(VoucherUrl) + "\"");
            strCommand.Append(",BarcodeImageUrl=\"" + WLMFunctions.comillas(BarcodeImageUrl) + "\"");
            strCommand.Append(" WHERE id='" + id + "'");
            ConexionDBInterna.ExecuteCommand(strCommand.ToString());
        }
        #endregion
    }




    public class AnuncioTransaccionCollection
    {
        private dbConnector ConexionDB;
        public BaseClassArray<AnuncioTransaccion> Elementos {get;set; }
        public AnuncioTransaccionCollection()
        {
        }
        public AnuncioTransaccionCollection(ref dbConnector dbConn)
        {

            string strCommand = "SELECT id FROM ANUNCIOTRANSACCIONES ";
            OdbcDataReader dataReader = ConexionDB.ExecuteReader(strCommand);
            Elementos = new BaseClassArray<AnuncioTransaccion>();
            while (dataReader.Read())
            {
                AnuncioTransaccion newItem = new AnuncioTransaccion(Convert.ToInt32(dataReader["id"]), ref ConexionDB);
                Elementos.Add(newItem);
            }
            dataReader.Close();
            dataReader.Dispose();
        }
    }
}